package com.zmn.oms.api.controller.open;

import com.alibaba.fastjson.JSON;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.constant.StatusConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.common.utils.validator.ValidateResult;
import com.zmn.common.utils.validator.ValidatorUtil;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.utils.AesUtil;
import com.zmn.oms.dubbo.dto.zmn.warranty.WarrantyListUserDRO;
import com.zmn.oms.dubbo.dto.zmn.warranty.WarrantyUserDRO;
import com.zmn.oms.dubbo.interfaces.zmn.normal.warranty.ZsNormalOrderWarrantyRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import com.zmn.oms.model.bo.order.OrderBO;
import com.zmn.oms.model.dto.order.open.*;
import com.zmn.oms.model.entity.chan.plat.ChannelInterface;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.order.open.AvailableTimeslotsVO;
import com.zmn.oms.model.vo.order.open.CreateOrderVO;
import com.zmn.oms.model.vo.order.open.OrderInfoVO;
import com.zmn.oms.zmn.business.interfaces.open.OpenOrderBService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * 类描述：订单接口
 *
 * @author liuying
 * @date 2019/02/16 17:35
 */
@RestController
@RequestMapping("/v1")
@Slf4j
public class OrderV1Controller extends OrderBaseController {

    private static final String TAG = "oms-open-api";
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private OpenOrderBService openOrderBService;
    @Autowired
    private WorkFlowContextBService workFlowContextBService;
    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private ZsNormalOrderWarrantyRemoteService zsNormalOrderWarrantyRemoteService;
    /**
     * 查询预约时间
     *
     * @param requestDTO 订单信息
     * @return
     */
    @PostMapping("/queryAvailableTimeslots")
    public ResultDTO queryAvailableTimes(HttpServletRequest request, RequestDTO requestDTO) {

        try {
            logger.info("{}#queryAvailableTimeslots#request：{}", TAG, requestDTO);

            // 验证参数
            super.validateData(request, requestDTO, true);

            AvailableTimeslotsQuery availableTimeslotsQuery = JSON.parseObject(requestDTO.getJsonData(), AvailableTimeslotsQuery.class);

            // 验证提交参数
            ValidateResult validateResult = ValidatorUtil.validator(availableTimeslotsQuery);
            if (!validateResult.isSuccess()) {
                logger.error("[{}] 参数错误：{}", TAG, validateResult.toString());
                return ResultDTO.fail(StatusConsts.ERROR_PARAMS, "参数错误：" + validateResult.toString());
            }

            List<AvailableTimeslotsVO> availableTimeslotsList = openOrderBService.queryAvailableTimeslots(availableTimeslotsQuery);

            logger.info("{}#queryAvailableTimeslots#response：{}", TAG, availableTimeslotsList);

            return ResultDTO.success(availableTimeslotsList);
        } catch (OmsBaseException e) {
            logger.info("{}#queryAvailableTimeslots：{}", TAG, e.getMessage());
            return ResultDTO.fail(Optional.ofNullable(e.getCode()).orElse(StatusConsts.STATUS_ERROR), e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return ResultDTO.fail("操作失败：" + e.getMessage());
        }
    }

    /**
     * 创建订单
     *
     * @param requestDTO 订单信息
     * @return
     */
    @PostMapping("/createOrder")
    public ResultDTO createOrder(HttpServletRequest request, RequestDTO requestDTO) {

        try {
            logger.info("{}#createOrder#request：{}", TAG, requestDTO);

            // 验证参数
            ChannelInterface channelInterface = super.validateData(request, requestDTO, false);

            CreateOrderDTO createOrderDTO = JSON.parseObject(requestDTO.getJsonData(), CreateOrderDTO.class);
            createOrderDTO.setOuterJsonData(requestDTO.getJsonData());
            createOrderDTO.setChannelId(channelInterface.getChannelId());

            // 判断新单or返修单
            int type = Optional.ofNullable(createOrderDTO.getType()).orElse(1);
            if (type != 1 && type != 2) {
                return ResultDTO.fail(StatusConsts.ERROR_PARAMS, "参数错误：type:[" +type+ "]" );
            }
            if (type == 2 && createOrderDTO.getReworkId() == null) {
                return ResultDTO.fail(StatusConsts.ERROR_PARAMS, "参数错误：缺少返修单号" );
            }

            // 判断是否厂商单
            int isFactoryOrder = Optional.ofNullable(createOrderDTO.getFactory()).orElse(1);
            if (Objects.equals(GlobalConsts.YES, isFactoryOrder)) {
                // 厂商产品功能取消，所有厂商产品设置为null。2020-7-28 wangxiaokun
                createOrderDTO.setFacProductId(null);
            }

            // 验证提交参数
            ValidateResult validateResult = ValidatorUtil.validator(createOrderDTO);
            if (!validateResult.isSuccess()) {
                logger.error("[{}] 参数错误：{}", TAG, validateResult.toString());
                return ResultDTO.fail(StatusConsts.ERROR_PARAMS, "参数错误：" + validateResult.toString());
            }

            // 解密相关字段
            this.decryptCreateOrderDTO(channelInterface, createOrderDTO);

            // 保存订单
            OrderBO orderBO = openOrderBService.createOrder(createOrderDTO);

            CreateOrderVO createOrderVO = new CreateOrderVO();
            createOrderVO.setOrderId(orderBO.getOrder().getOrderId());
            logger.info("{}#createOrder#response：{}", TAG, createOrderVO);

            // 工单自动流转
            OrderWork orderWork = orderBO.getOrderWork();
            workFlowContextBService.asyncAutoFlow(orderWork.getOrderId(),orderWork.getWorkId());

            return ResultDTO.success(createOrderVO);
        } catch (OmsBaseException e) {
            logger.error("{}#createOrder：{}{}", TAG, e.getMessage(), e);
            return ResultDTO.fail(Optional.ofNullable(e.getCode()).orElse(StatusConsts.STATUS_ERROR), e.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ResultDTO.fail("操作失败：" + e.getMessage());
        }

    }

    /**
     * 渠道支付
     *
     * @param requestDTO 订单信息
     * @return
     */
    @PostMapping("/payOrder")
    public ResultDTO payOrder(HttpServletRequest request, RequestDTO requestDTO) {

        try {
            logger.info("{}#payOrder#request：{}", TAG, requestDTO);

            // 验证参数
            ChannelInterface channelInterface = super.validateData(request, requestDTO, false);

            PayOrderDTO payOrderDTO = JSON.parseObject(requestDTO.getJsonData(), PayOrderDTO.class);
            payOrderDTO.setChannelId(channelInterface.getChannelId());

            // 验证提交参数
            ValidateResult validateResult = ValidatorUtil.validator(payOrderDTO);
            if (!validateResult.isSuccess()) {
                logger.error("[{}] 参数错误：{}", TAG, validateResult.toString());
                return ResultDTO.fail(StatusConsts.ERROR_PARAMS, "参数错误：" + validateResult.toString());
            }

            // 渠道支付
            openOrderBService.channelPrepayOrder(payOrderDTO);

            // 工单自动流转
            workFlowContextBService.asyncAutoFlow(payOrderDTO.getOrderId(),payOrderDTO.getOrderId());

            return ResultDTO.success();
        } catch (OmsBaseException e) {
            logger.info("{}#payOrder：{}", TAG, e.getMessage());
            return ResultDTO.fail(Optional.ofNullable(e.getCode()).orElse(StatusConsts.STATUS_ERROR), e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return ResultDTO.fail("操作失败：" + e.getMessage());
        }
    }

    /**
     * 取消订单
     *
     * @param requestDTO 订单信息
     * @return
     */
    @PostMapping("/cancelOrder")
    public ResultDTO cancelOrder(HttpServletRequest request, RequestDTO requestDTO) {

        try {
            logger.info("{}#cancelOrder：{}", TAG, requestDTO);

            // 验证参数
            ChannelInterface channelInterface = super.validateData(request, requestDTO, false);

            CancelOrderDTO cancelOrderDTO = JSON.parseObject(requestDTO.getJsonData(), CancelOrderDTO.class);
            cancelOrderDTO.setChannelId(channelInterface.getChannelId());

            // 验证提交参数
            ValidateResult validateResult = ValidatorUtil.validator(cancelOrderDTO);
            if (!validateResult.isSuccess()) {
                logger.error("[{}] 参数错误：{}", TAG, validateResult.toString());
                return ResultDTO.fail(StatusConsts.ERROR_PARAMS, "参数错误：" + validateResult.toString());
            }

            // 渠道支付
            openOrderBService.cancelOrder(cancelOrderDTO);

            return ResultDTO.success();
        } catch (OmsBaseException e) {
            logger.info("{}#cancelOrder：{}", TAG, e.getMessage());
            return ResultDTO.fail(Optional.ofNullable(e.getCode()).orElse(StatusConsts.STATUS_ERROR), e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return ResultDTO.fail("操作失败：" + e.getMessage());
        }
    }

    /**
     * 查询订单信息
     *
     * @param requestDTO 订单信息
     * @return
     */
    @PostMapping("/queryOrder")
    public ResultDTO queryOrderInfo(HttpServletRequest request, RequestDTO requestDTO) {

        try {
            logger.info("{}#queryOrder：{}", TAG, requestDTO);

            // 验证参数
            ChannelInterface channelInterface = super.validateData(request, requestDTO, true);
            OrderQueryDTO orderQueryDTO = JSON.parseObject(requestDTO.getJsonData(), OrderQueryDTO.class);
            orderQueryDTO.setChannelId(channelInterface.getChannelId());

            // 验证提交参数
            ValidateResult validateResult = ValidatorUtil.validator(orderQueryDTO);
            if (!validateResult.isSuccess()) {
                logger.error("[{}] 参数错误：{}", TAG, validateResult.toString());
                return ResultDTO.fail(StatusConsts.ERROR_PARAMS, "参数错误：" + validateResult.toString());
            }

            OrderInfoVO orderInfoVO = openOrderBService.queryOrder(orderQueryDTO);

            logger.info("{}#queryOrder#response：{}", TAG, orderInfoVO);

            return ResultDTO.success(orderInfoVO);
        } catch (OmsBaseException e) {
            logger.info("{}#queryOrder：{}", TAG, e.getMessage());
            return ResultDTO.fail(Optional.ofNullable(e.getCode()).orElse(StatusConsts.STATUS_ERROR), e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return ResultDTO.fail("操作失败：" + e.getMessage());
        }
    }

    /**
     * 根据用户获取保修卡
     * @param userId
     * @return
     */
    @GetMapping("/listWarrantyByUserId")
    public ResponseDTO listWarrantyByUserId(Long userId) {
        try {
            logger.info("{}#listWarrantyByUserId：{}", TAG, userId);
            ResponseDTO<List<WarrantyListUserDRO>> listResponseDTO = zsNormalOrderWarrantyRemoteService.listWarrantyByUserId(userId);
            return listResponseDTO;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ResponseDTO.fail("操作失败");
        }
    }

    /**
     * 获取保修卡详情
     * @param orderId
     * @param codeStr
     * @return
     */
    @GetMapping("/findWarrantyDetailByOrderIdAndCode")
    public ResponseDTO findWarrantyDetailByOrderIdAndCode (Long orderId, String codeStr) {
        try {
            logger.info("{}#findWarrantyDetailByOrderIdAndCode：{}", TAG, orderId, codeStr);
            ResponseDTO<WarrantyUserDRO> warrantyDetailByOrderIdAndCode = zsNormalOrderWarrantyRemoteService.findWarrantyDetailByOrderIdAndCode(orderId, codeStr);
            return warrantyDetailByOrderIdAndCode;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return ResponseDTO.fail("操作失败");
        }
    }

    /**
     * 解密订单创建数据的加密数据
     * @param ChannelInterface
     * @param createOrderDTO
     */
    private void decryptCreateOrderDTO(ChannelInterface channelInterface, CreateOrderDTO createOrderDTO) {

        // 参数判断
        if (Objects.isNull(channelInterface) || Objects.isNull(createOrderDTO)) {
            return;
        }

        // 密码
        String password = channelInterface.getAppSecret();

        // 加密字段
        String filedEncrypt = createOrderDTO.getFiledEncrypt();
        if (StringUtil.isBlank(filedEncrypt)) {
            return;
        }

        // 解析字段列表
        List<String> filedList = StringUtil.split(filedEncrypt,",", String.class);
        if (CollectionUtil.isNullOrEmpty(filedList)) {
            return;
        }

        // 联系人解密
        String contactName = createOrderDTO.getContactName();
        if (filedList.contains("contactName") && StringUtil.isNotBlank(contactName)) {
            createOrderDTO.setContactName(AesUtil.decrypt(password,contactName));
        }

        // 电话
        String telephone = createOrderDTO.getTelephone();
        if (filedList.contains("telephone") && StringUtil.isNotBlank(telephone)) {
            createOrderDTO.setTelephone(AesUtil.decrypt(password,telephone));
        }

        // 街道
        String street = createOrderDTO.getStreet();
        if (filedList.contains("street") && StringUtil.isNotBlank(street)) {
            createOrderDTO.setStreet(AesUtil.decrypt(password,street));
        }

        // 地址
        String address = createOrderDTO.getAddress();
        if (filedList.contains("address") && StringUtil.isNotBlank(address)) {
            createOrderDTO.setAddress(AesUtil.decrypt(password,address));
        }
    }
}
